#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "UDPCommunication.h"
#include <winsock2.h>
#include <cstring>
#include <thread>
#include <iostream>
#include <sstream>
#include"TimeSync.h"


#pragma comment(lib, "ws2_32.lib")

UDPCommunicator::UDPCommunicator(const std::string& id, const std::string& addr)
    : deviceId(id), broadcastAddress(addr), receiving(false), sockfd(INVALID_SOCKET) {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup failed: " << WSAGetLastError() << std::endl;
        return;
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == INVALID_SOCKET) {
        std::cerr << "socket creation failed: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return;
    }

    int broadcastEnable = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char*)&broadcastEnable, sizeof(broadcastEnable)) == SOCKET_ERROR) {
        std::cerr << "setsockopt broadcast failed: " << WSAGetLastError() << std::endl;
        closesocket(sockfd);
        WSACleanup();
        sockfd = INVALID_SOCKET;
    }
}

// 序列化时对特殊字符转义（避免|分隔符冲突）
std::string escapeString(const std::string& s) {
    std::string res;
    for (char c : s) {
        if (c == '|') res += "\\|";
        else if (c == '\\') res += "\\\\";
        else res += c;
    }
    return res;
}

// 反序列化时还原转义字符
std::string unescapeString(const std::string& s) {
    std::string res;
    for (size_t i = 0; i < s.size(); i++) {
        if (s[i] == '\\' && i + 1 < s.size()) {
            if (s[i + 1] == '|') {
                res += '|';
                i++;
            }
            else if (s[i + 1] == '\\') {
                res += '\\';
                i++;
            }
            else {
                res += s[i];
            }
        }
        else {
            res += s[i];
        }
    }
    return res;
}


bool convertIpAddress(const std::string& ip, in_addr& addr) {
#ifdef _WIN32
    // 直接用 Windows 版 inet_pton（Vista+ 支持 IPv4/IPv6）
	addr.s_addr = inet_addr(ip.c_str());
	if (addr.s_addr == INADDR_NONE) {
		std::cerr << "Invalid IP address: " << ip << std::endl;
		return false;
}
	return true;
#else
    // Linux 等系统逻辑不变
    return inet_pton(AF_INET, ip.c_str(), &addr) == 1;
#endif
}

void UDPCommunicator::sendEventSummary(const EventSummary& event) {
    if (sockfd == INVALID_SOCKET) return;  // 修正判断条件（原sockfd < 0不适合Windows的SOCKET类型）

    struct sockaddr_in destAddr;
    memset(&destAddr, 0, sizeof(destAddr));
    destAddr.sin_family = AF_INET;
    destAddr.sin_port = htons(8888);

    // 使用新的转换函数并添加错误检查
    if (!convertIpAddress(broadcastAddress.c_str(), destAddr.sin_addr)) {
        std::cerr << "Invalid broadcast address: " << broadcastAddress << std::endl;
        return;
    }

    // 序列化代码保持不变...
    std::string serialized = event.deviceId + "|" +
        std::to_string(event.timestamp) + "|" +
        std::to_string(event.confidence) + "|" +
        event.eventType;

    sendto(sockfd, serialized.c_str(), serialized.size(), 0,
        (struct sockaddr*)&destAddr, sizeof(destAddr));
}




void UDPCommunicator::startReceiving(std::function<void(const EventSummary&)> callback) {
    if (receiving || sockfd == INVALID_SOCKET) return;

    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(8888);

    if (bind(sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
        std::cerr << "bind failed: " << WSAGetLastError() << std::endl;
        return;
    }

    receiving = true;
    std::thread(&UDPCommunicator::receiverThread, this, callback).detach();
}

void UDPCommunicator::receiverThread(std::function<void(const EventSummary&)> callback) {
    char buffer[1024];
    struct sockaddr_in cliaddr;
    int len = sizeof(cliaddr);
    fd_set readSet;
    timeval timeout;

    while (receiving) {
        // 使用select实现超时机制，避免recvfrom阻塞无法退出
        FD_ZERO(&readSet);
        FD_SET(sockfd, &readSet);
        timeout.tv_sec = 1;  // 1秒超时
        timeout.tv_usec = 0;

        int activity = select(0, &readSet, nullptr, nullptr, &timeout);
        if (activity < 0) {
            if (receiving) {  // 非主动停止时才报错
                std::cerr << "Select error: " << WSAGetLastError() << std::endl;
            }
            continue;
        }
        else if (activity == 0) {
            continue;  // 超时，继续循环检查receiving状态
        }

        // 确认套接字有数据可读
        if (FD_ISSET(sockfd, &readSet)) {
            int n = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0,
                (struct sockaddr*)&cliaddr, &len);
            if (n < 0) {
                if (receiving) {  // 非主动停止时才报错
                    std::cerr << "Receive error: " << WSAGetLastError() << std::endl;
                }
                continue;
            }
            else if (n == 0) {
                continue;  // 空数据，忽略
            }

            buffer[n] = '\0';  // 确保字符串终止

            // 解析接收到的数据
            EventSummary event;
            std::string data(buffer);
            size_t pos = 0;
            std::vector<std::string> parts;

            // 分割字符串，增强容错性
            while (pos != std::string::npos) {
                size_t next = data.find('|', pos);
                if (next == std::string::npos) {
                    parts.push_back(data.substr(pos));
                    break;
                }
                parts.push_back(data.substr(pos, next - pos));
                pos = next + 1;
            }

            // 验证数据格式是否正确
            if (parts.size() != 4) {
                std::cerr << "Invalid data format: " << data << std::endl;
                continue;
            }

            // 安全解析各字段
            try {
                event.deviceId = parts[0];
                event.timestamp = std::stoull(parts[1]);
                event.confidence = std::stof(parts[2]);
                event.eventType = parts[3];
            }
            catch (const std::exception& e) {
                std::cerr << "Data parse error: " << e.what() << " for data: " << data << std::endl;
                continue;
            }

            // 过滤自身发送的事件
            if (event.deviceId == deviceId) {
                continue;
            }

            // 处理时间同步事件（如果需要）
            if (event.eventType == "TIME_SYNC") {
                TimeSync::processReceivedTimestamp(event.timestamp);
                continue;
            }

            // 调用回调函数处理事件
            callback(event);
        }
    }
}

void UDPCommunicator::stopReceiving() {
    receiving = false;
    if (sockfd != INVALID_SOCKET) {
        sendEventSummary(EventSummary{}); // 唤醒接收线程
        closesocket(sockfd);
        sockfd = INVALID_SOCKET;
    }
    WSACleanup();
}